home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: delta / whiteline CD Series - delta.iso / progtool / c / dev_lib1 / src / dev_lib.c next >
C/C++ Source or Header  |  1995-11-25  |  27KB  |  1,342 lines

  1. /*
  2.  * Project    :        Device Library Version 0.20beta
  3.  * Module     :        dev_lib.c
  4.  * Author     :        Jan Kriesten
  5.  * Date       :     07.05.1995
  6.  *
  7.  * Description:        main routines to install/deinstall devices
  8.  *
  9.  * Tabsize 4
  10.  */
  11.  
  12. /*-----------------------------*/
  13. /*--- includes              ---*/
  14. /*-----------------------------*/
  15.  
  16. #include <import.h>
  17. #include <device.h>
  18.  
  19. #include "dev_misc.h"
  20. #include "types.h"
  21. #include "port.h"
  22.  
  23. #include <export.h>
  24.  
  25. /*-----------------------------*/
  26. /*--- defines               ---*/
  27. /*-----------------------------*/
  28.  
  29. #define        BMAPSTART        5
  30.  
  31. #define        MAX_BLOCK        4096L
  32. #define        MAX_SPEEDS        25
  33.  
  34. /*-----------------------------*/
  35. /*--- types                 ---*/
  36. /*-----------------------------*/
  37.  
  38. typedef struct
  39. {
  40.     /*
  41.      * Sichtbar für den User:
  42.      */
  43.     DEV_LIST    device;        /* Liste der Device-Namen    */
  44.     
  45.     /*
  46.      * Sytemdaten:
  47.      */
  48.     WORD        bios;            /* BIOS-Nr. des Devices                    */
  49.     WORD        func_num;        /* "normierte" Bconmap-Zugriffsnummer    */
  50.     BYTE        *dopen;            /* Name des Devices für Fopen( )        */
  51.     
  52.     /*
  53.      * Daten zur Verwaltung des Devices:
  54.      */
  55.     BOOLEAN        is_open;        /* TRUE, falls Device geöffnet            */
  56.     WORD        dhandle;        /* handle, falls mit Fopen( ) geöffnet    */
  57.     WORD        curr_pos;        /* aktulle Position im Puffer            */
  58.     WORD        num_read;        /* Anzahl der eingelesenen Zeichen        */
  59.     
  60.     BYTE        *buf;            /* Zeiger Blockdevice-Puffer            */
  61.     LONG        *speeds;        /* Liste der einstellbaren DTE-speeds    */
  62.     CHAN_INFO    *chan_info;        /* Struktur unter FastSeriell            */
  63.     MAPTAB        *func_map;        /* Tabelle der einzelnen Funktionen        */
  64.     WORD        oldIBufSize,
  65.                 oldOBufSize;
  66.     BYTE        *oldIBufPtr,
  67.                 *oldOBufPtr;
  68.     LONG        ioctrlmap[6];    /* Index der möglichen Fcntl-Funktionen    */
  69. } DEVICES;
  70.  
  71. typedef union
  72. {
  73.     UWORD word;
  74.     struct
  75.     {
  76.         UWORD    bit7_15    : 9;
  77.         UWORD    bit5_6    : 2;
  78.         UWORD    bit3_4    : 2;
  79.         UWORD    bit2    : 1;
  80.         UWORD    bit1    : 1;
  81.         UWORD    bit0    : 1;
  82.     } bits;
  83. } UCR;
  84.  
  85. /*-----------------------------*/
  86. /*--- variables             ---*/
  87. /*-----------------------------*/
  88.  
  89. LOCAL    UWORD        atari,
  90.                     tos,
  91.                     MiNT;
  92.  
  93. LOCAL    FSER_INFO    *fser;
  94. LOCAL    RSVF_DEV    *rsvf;
  95.  
  96. LOCAL    BOOLEAN        has_bconmap,
  97.                     has_drv_u;
  98.  
  99. LOCAL    BYTE        *d_name[] =    {
  100.                                     "Modem 1",
  101.                                     "Modem 2",
  102.                                     "Serial 1",
  103.                                     "Serial 2",
  104.                                     "Midi"
  105.                                 },
  106.                     *d_open[] =    {
  107.                                     "MODEM1",
  108.                                     "MODEM2",
  109.                                     "SERIAL1",
  110.                                     "SERIAL2",
  111.                                 };
  112.  
  113. LOCAL    LONG        speeds[] =    {
  114.                                     19200L,
  115.                                     9600L,
  116.                                     4800L,
  117.                                     3600L,
  118.                                     2400L,
  119.                                     2000L,
  120.                                     1800L,
  121.                                     1200L,
  122.                                     600L,
  123.                                     300L,
  124.                                     200L,
  125.                                     150L,
  126.                                     134L,
  127.                                     110L,
  128.                                     75L,
  129.                                     50L,
  130.                                     -1L
  131.                                 };
  132.                                 
  133. LOCAL LONG            midi_speeds[] = { 31250, -1 };
  134.  
  135. LOCAL    DEVICES        *devices;
  136. LOCAL    LONG        cntrls[4];
  137.  
  138. LOCAL    VOID        (*pause_1)( VOID );
  139. EXTERN    VOID        (*pause_2)( VOID );
  140.  
  141. /*--- prototypes            ---*/
  142.  
  143. LOCAL BOOLEAN    InitStdDevices    ( MAPTAB *maps, BOOLEAN has_bconmap, WORD num_devices );
  144. LOCAL BOOLEAN    InitRSVFDevices    ( MAPTAB *maps, RSVF_DEV *dev );
  145. LOCAL BOOLEAN    CreateSpeedlist    ( DEVICES *dev );
  146. LOCAL VOID        GetFcntlSpeeds    ( DEVICES *dev );
  147. LOCAL VOID        GetFserSpeeds    ( DEVICES *dev );
  148. LOCAL VOID        FreeSpeedlist    ( DEVICES *dev );
  149. LOCAL VOID        SetDevFunctions    ( DEVICES *dev );
  150. LOCAL VOID        SetPortProtokoll( DEVICES *dev );
  151. LOCAL BOOLEAN    DevicePickup    ( DEVICES *dev );
  152. LOCAL BOOLEAN    DeviceSendBlock    ( DEVICES *dev, BYTE *block, LONG len, BOOLEAN tst_dcd );
  153.  
  154. /*-----------------------------*/
  155. /*--- global functions      ---*/
  156. /*-----------------------------*/
  157.  
  158. /*-------------------------------------------------------------------*/ 
  159.  
  160. GLOBAL DEV_LIST *InitDevices( VOID *timerelease1, VOID *timerelease2 )
  161. {
  162.     /*
  163.      * Initialisiert alle vorhandenen Ports/Devices.
  164.      */
  165.     WORD        num_devices;
  166.     BOOLEAN        mega;
  167.     MAPTAB        *maps;
  168.  
  169.     devices     = NULL;
  170.     tos         = get_tos( );
  171.     has_drv_u   = has_drive_u( );
  172.     has_bconmap = (Bconmap( 0 )==0L);    
  173.     
  174.     pause_1     = timerelease1;
  175.     pause_2     = timerelease2;
  176.  
  177.     atari = getcookie( '_MCH', cntrls ) ? (UWORD) (cntrls[0]>>16) : 0;
  178.     mega  = (UWORD) cntrls[0] ? TRUE : FALSE;
  179.     fser  = getcookie( 'FSER', cntrls ) ? (FSER_INFO *) cntrls[0] : NULL;
  180.     MiNT  = getcookie( 'MiNT', cntrls ) ? (WORD)        cntrls[0] : 0;
  181.     rsvf  = getcookie( 'RSVF', cntrls ) ? (RSVF_DEV  *) cntrls[0] : NULL;
  182.     
  183.     /*
  184.      * Set MiNT process execution domain (to let Fread, Fwrite
  185.      * behave as stated in the terminal settings):
  186.      */
  187.     if( MiNT && !rsvf && !fser )
  188.         Pdomain( 1 );
  189.     
  190.     if( has_bconmap )
  191.     {
  192.         BCONMAP *bmap = (BCONMAP *) Bconmap( -2 );
  193.         
  194.         maps        = bmap->maptab;
  195.         num_devices = bmap->maptabsize;
  196.         
  197.         if( !maps )
  198.             has_bconmap = FALSE;
  199.     }
  200.     else
  201.         maps        = NULL;
  202.     
  203.     switch( atari )
  204.     {
  205.         case 0:
  206.         case 3:
  207.                 num_devices = 1;
  208.                 break;
  209.         case 1:
  210.                 num_devices = mega ? 3 : 1;
  211.                 break;
  212.         case 2:
  213.                 num_devices = 4;
  214.                 break;
  215.     }
  216.     
  217.     if( !InitStdDevices( maps, has_bconmap, num_devices ) )
  218.         return( NULL );
  219.     
  220.     if( rsvf && !InitRSVFDevices( maps, rsvf ) )
  221.         return( NULL );
  222.     
  223.     return( (devices) ? &(devices->device) : NULL );
  224. }
  225.  
  226. /*-------------------------------------------------------------------*/ 
  227.  
  228. GLOBAL VOID TermDevices( VOID )
  229. {
  230.     /*
  231.      * Gibt den Speicher der Device-Liste wieder frei:
  232.      */
  233.     
  234.     DEVICES    *dwalk;
  235.     
  236.     for( dwalk=devices; dwalk; dwalk=devices )
  237.     {
  238.         CloseDevice( (DEV_LIST *) dwalk );
  239.         
  240.         devices = (DEVICES *) dwalk->device.next;
  241.         free( dwalk );
  242.     }
  243. }
  244.  
  245. /*-------------------------------------------------------------------*/ 
  246.  
  247. GLOBAL BOOLEAN OpenDevice( DEV_LIST *port )
  248. {
  249.     /*
  250.      * Öffnet port und stellt alle entsprechenden Funktionen zusammen.
  251.      */
  252.     DEVICES    *dev;
  253.     
  254.     dev = (DEVICES *) port;
  255.  
  256.     if( dev->is_open )
  257.         return( FALSE );
  258.     
  259.     /*
  260.      * Erst den Standard-Aux umsetzen:
  261.      */
  262.     if( has_bconmap && dev->bios>5 )
  263.         Bconmap( dev->bios );
  264.     
  265.     /*
  266.      * Bei FastSerial keine Blockdevice-Routinen benutzen:
  267.      */
  268.     if( fser && (dev->bios==1 || dev->bios>5) )
  269.     {
  270.         CHAN_INFO    *tst;
  271.         
  272.         tst = (CHAN_INFO *) Rsconf( -3, -3, -1, -1, -1, -1 );
  273.         
  274.         if( tst->task>0 )
  275.             return( FALSE );
  276.         
  277.         dev->chan_info = tst;
  278.         dev->is_open   = TRUE;
  279.     }
  280.     
  281.     /*
  282.      * Testen, ob es sich um ein Block-Device handelt:
  283.      */
  284.     if( !dev->is_open && dev->dopen )
  285.     {
  286.         BYTE    path[64];
  287.         LONG    rc;
  288.         
  289.         strcpy( path, "U:\\DEV\\" );
  290.         strcpy( path+7, dev->dopen );
  291.     
  292.         if( (rc=Fopen( path, FO_RW|O_NDELAY ))>=0 )
  293.         {
  294.             dev->dhandle = (WORD) rc;
  295.             dev->is_open = TRUE;
  296.             
  297.             if( (dev->buf=(BYTE *) malloc( MAX_BLOCK * sizeof( BYTE ) ))==NULL )
  298.             {
  299.                 CloseDevice( port );
  300.                 return( FALSE );
  301.             }
  302.         }
  303.         /*
  304.          * Falls -36 (EACCDN) zurückgegeben wird, so wurde das Device
  305.          * schon von einer anderen Applikation geöffnet.
  306.          */
  307.         else if( rc==-36L )
  308.             return( FALSE );
  309.     }
  310.     
  311.     dev->is_open = TRUE;
  312.     
  313.     SetDevFunctions( dev );
  314.     SetPortProtokoll( dev );
  315.     
  316.     if( !CreateSpeedlist( dev ) )
  317.         CloseDevice( port );
  318.     else
  319.         StartReceiver( port );
  320.     
  321.     return( dev->is_open );
  322. }
  323.  
  324. /*-------------------------------------------------------------------*/ 
  325.  
  326. GLOBAL VOID CloseDevice( DEV_LIST *port )
  327. {
  328.     /*
  329.      * Schließt port und gibt den Speicher wieder frei
  330.      */
  331.     DEVICES    *dev;
  332.     
  333.     dev = (DEVICES *) port;
  334.  
  335.     if( !dev->is_open )
  336.         return;
  337.     
  338.     if( dev->dhandle>=0 )
  339.     {
  340.         Fclose( dev->dhandle );
  341.         dev->dhandle = -1;
  342.     }
  343.     
  344.     if( dev->buf )
  345.     {
  346.         free( dev->buf );
  347.         dev->buf = NULL;
  348.     }
  349.     
  350.     if( dev->oldIBufPtr )
  351.     {
  352.         IOREC    *iorec;
  353.         BYTE    *b;
  354.         
  355.         iorec = dev->func_map->iorec;
  356.         b     = iorec->ibuf;
  357.         
  358.         SetIorec( iorec, dev->oldIBufPtr, dev->oldIBufSize );
  359.         
  360.         (MiNT) ? Mfree( b ) : free( b );
  361.         dev->oldIBufPtr  = NULL;
  362.     }
  363.     
  364.     if( dev->oldOBufPtr )
  365.     {
  366.         IOREC    *iorec;
  367.         BYTE    *b;
  368.         
  369.         iorec = dev->func_map->iorec;
  370.         ++iorec;
  371.         b = iorec->ibuf;
  372.         
  373.         SetIorec( iorec, dev->oldOBufPtr, dev->oldOBufSize );
  374.  
  375.         (MiNT) ? Mfree( b ) : free( b );
  376.         dev->oldOBufPtr  = NULL;
  377.     }
  378.     
  379.     FreeSpeedlist( dev );
  380.     
  381.     dev->is_open = FALSE;
  382.         
  383.     return;
  384. }
  385.  
  386. /*-------------------------------------------------------------------*/ 
  387.  
  388. GLOBAL WORD GetBiosNr( DEV_LIST *dev )
  389. {
  390.     return( ((DEVICES *) dev)->bios );
  391. }
  392.  
  393. /*-------------------------------------------------------------------*/ 
  394.  
  395. GLOBAL LONG *GetSpeedList( DEV_LIST *dev )
  396. {
  397.     return( ((DEVICES *) dev)->speeds );
  398. }
  399.  
  400. /*-------------------------------------------------------------------*/ 
  401.  
  402. GLOBAL LONG SetDTESpeed( DEV_LIST *port, LONG speed )
  403. {
  404.     DEVICES    *dev;
  405.     
  406.     dev  = (DEVICES *) port;
  407.     
  408.     /*
  409.      * Erst den Standard-Aux umsetzen:
  410.      */
  411.     if( has_bconmap && dev->bios>5 )
  412.         Bconmap( dev->bios );
  413.     
  414.     if( dev->dhandle>=0 )
  415.     {
  416.         cntrls[0] = speed;
  417.         
  418.         if( !Fcntl( dev->dhandle, cntrls, TIOCIBAUD ) )
  419.             dev->device.curr_dte = speed;
  420.     }
  421.     else if( dev->bios==3 )
  422.     {
  423.         return( dev->device.curr_dte );
  424.     }
  425.     else if( fser )
  426.     {
  427.         WORD        i=0;
  428.         BAUD_INFO    *help;
  429.         
  430.         help = (fser->baud_table_flag) ? dev->chan_info->alt_baud_table : dev->chan_info->baud_table;
  431.  
  432.         while( help->baudrate )
  433.         {
  434.             if( help->baudrate==speed )
  435.                 break;
  436.             i++, help++;
  437.         }
  438.         
  439.         if( help->baudrate>0 )
  440.         {
  441.             Rsconf( i, -1, -1, -1, -1, -1 );
  442.             dev->device.curr_dte = speed;
  443.         }
  444.     }
  445.     else
  446.     {
  447.         WORD    i=0;
  448.         LONG    *help=dev->speeds;
  449.         
  450.         while( *help>0 )
  451.         {
  452.             if( *help==speed )
  453.                 break;
  454.             i++, help++;
  455.         }
  456.         
  457.         if( *help>0 )
  458.         {
  459.             Rsconf( i, -1, -1, -1, -1, -1 );
  460.             dev->device.curr_dte = speed;
  461.         }
  462.     }
  463.     
  464.     return( dev->device.curr_dte );
  465. }
  466.  
  467. /*-------------------------------------------------------------------*/ 
  468.  
  469. GLOBAL VOID StartReceiver( DEV_LIST *port )
  470. {
  471.     DEVICES    *dev;
  472.     
  473.     dev  = (DEVICES *) port;
  474.     
  475.     if( dev->dhandle>=0 )
  476.         Fcntl( dev->dhandle, NULL, TIOCSTART );
  477. }
  478.  
  479. /*-------------------------------------------------------------------*/ 
  480.  
  481. GLOBAL VOID StopReceiver( DEV_LIST *port )
  482. {
  483.     DEVICES    *dev;
  484.     
  485.     dev  = (DEVICES *) port;
  486.     
  487.     if( dev->dhandle>=0 )
  488.         Fcntl( dev->dhandle, NULL, TIOCSTOP );
  489. }
  490.  
  491. /*-------------------------------------------------------------------*/ 
  492.  
  493. GLOBAL WORD SetTxBuffer( DEV_LIST *port, WORD size )
  494. {
  495.     DEVICES    *dev;
  496.     IOREC    *iorec;
  497.     BYTE    *mem, *b=NULL;
  498.     
  499.     dev  = (DEVICES *) port;
  500.     
  501.     if( dev->dhandle>=0 )
  502.     {
  503.         cntrls[0] = cntrls[1] = cntrls[2] = -1L;
  504.         cntrls[3] = (LONG) size;
  505.         
  506.         if( !Fcntl( dev->dhandle, cntrls, TIOCBUFFER ) )
  507.             return( (WORD) cntrls[3] );
  508.     }
  509.     
  510.     if( (mem=(BYTE *) (MiNT ? Mxalloc( size, 0x23 ) : malloc( size )))==NULL )
  511.         return( -1 );
  512.     
  513.     iorec = dev->func_map->iorec;
  514.     ++iorec;
  515.     
  516.     if( !dev->oldOBufPtr )
  517.     {
  518.         dev->oldOBufSize = iorec->ibufsiz;
  519.         dev->oldOBufPtr  = iorec->ibuf;
  520.     }
  521.     else
  522.         b = iorec->ibuf;
  523.     
  524.     SetIorec( iorec, mem, size );
  525.     
  526.     if( b )
  527.     {
  528.         (MiNT) ? Mfree( b ) : free( b );
  529.     }
  530.     
  531.     return( size );
  532. }
  533.  
  534. /*-------------------------------------------------------------------*/ 
  535.  
  536. GLOBAL WORD GetTxBuffer( DEV_LIST *port )
  537. {
  538.     DEVICES    *dev;
  539.     
  540.     dev  = (DEVICES *) port;
  541.     
  542.     if( dev->dhandle>=0 )
  543.     {
  544.         cntrls[0] = cntrls[1] = cntrls[2] = cntrls[3] = -1L;
  545.         
  546.         if( !Fcntl( dev->dhandle, cntrls, TIOCBUFFER ) )
  547.             return( (WORD) cntrls[3] );
  548.     }
  549.  
  550.     return( -1 );
  551. }
  552.  
  553. /*-------------------------------------------------------------------*/ 
  554.  
  555. GLOBAL WORD SetRxBuffer( DEV_LIST *port, WORD size )
  556. {
  557.     DEVICES    *dev;
  558.     IOREC    *iorec;
  559.     BYTE    *mem, *b=NULL;
  560.     
  561.     dev  = (DEVICES *) port;
  562.     
  563.     if( dev->dhandle>=0 )
  564.     {
  565.         cntrls[0] = (LONG) size;
  566.         cntrls[1] = (LONG) (size >> 2);
  567.         cntrls[2] = (LONG) ((size + size + size) >> 2);
  568.         cntrls[3] = -1L;
  569.         
  570.         if( !Fcntl( dev->dhandle, cntrls, TIOCBUFFER ) )
  571.             return( (WORD) cntrls[0] );
  572.     }
  573.     
  574.     if( (mem=(BYTE *) (MiNT ? Mxalloc( size, 0x23 ) : malloc( size )))==NULL )
  575.         return( -1 );
  576.     
  577.     iorec = dev->func_map->iorec;
  578.     
  579.     if( !dev->oldIBufPtr )
  580.     {
  581.         dev->oldIBufSize = iorec->ibufsiz;
  582.         dev->oldIBufPtr  = iorec->ibuf;
  583.     }
  584.     else
  585.         b = iorec->ibuf;
  586.     
  587.     SetIorec( iorec, mem, size );
  588.     
  589.     if( b )
  590.     {
  591.         (MiNT) ? Mfree( b ) : free( b );
  592.     }
  593.     
  594.     return( size );
  595. }
  596.  
  597. /*-------------------------------------------------------------------*/ 
  598.  
  599. GLOBAL WORD GetRxBuffer( DEV_LIST *port )
  600. {
  601.     DEVICES    *dev;
  602.     
  603.     dev  = (DEVICES *) port;
  604.     
  605.     if( dev->dhandle>=0 )
  606.     {
  607.         cntrls[0] = cntrls[1] = cntrls[2] = cntrls[3] = -1L;
  608.         
  609.         if( !Fcntl( dev->dhandle, cntrls, TIOCBUFFER ) )
  610.             return( (WORD) cntrls[0] );
  611.     }
  612.  
  613.     return( -1 );
  614. }
  615.  
  616. /*-------------------------------------------------------------------*/ 
  617.  
  618. GLOBAL BOOLEAN PortSendByte( DEV_LIST *port, BYTE c )
  619. {
  620.     DEVICES    *dev;
  621.     
  622.     dev = (DEVICES *) port;
  623.     
  624.     if( dev->dhandle>=0 )
  625.         return( DeviceSendBlock( dev, &c, 1L, FALSE ) );
  626.     else if( dev->bios>=0 )
  627.     {
  628.         while( !Bcostat( dev->bios==3 ? 4 : dev->bios ) )
  629.         {
  630.             if( pause_1 )
  631.                 pause_1( );
  632.         }
  633.         
  634.         Bconout( dev->bios, c );
  635.         
  636.         return( TRUE );
  637.     }
  638.     
  639.     return( FALSE );
  640. }
  641.  
  642. /*-------------------------------------------------------------------*/ 
  643.  
  644. GLOBAL BOOLEAN PortSendBlock( DEV_LIST *port, BYTE *block, LONG len, BOOLEAN tst_dcd )
  645. {
  646.     DEVICES    *dev;
  647.     
  648.     dev = (DEVICES *) port;
  649.     
  650.     if( dev->dhandle>=0 )
  651.         return( DeviceSendBlock( dev, block, len, tst_dcd ) );
  652.     else if( dev->bios==3 )
  653.     {
  654.         Midiws( (WORD) len-1, block );
  655.         return( TRUE );
  656.     }
  657.     else if( dev->bios>=0 )
  658.         return( SendBlock( dev, block, len, tst_dcd ) );
  659.     
  660.     return( FALSE );
  661. }
  662.  
  663. /*-------------------------------------------------------------------*/ 
  664.  
  665. GLOBAL WORD PortGetByte( DEV_LIST *port )
  666. {
  667.     DEVICES    *dev;
  668.     
  669.     dev = (DEVICES *) port;
  670.     
  671.     if( dev->dhandle>=0 || dev->bios>=0 )
  672.     {
  673.         
  674.         while( !CharAvailable( port ) )
  675.         {
  676.             if( !IsCarrier( port ) )
  677.                 return( -1 );
  678.             
  679.             if( pause_1 )
  680.                 pause_1( );
  681.         }
  682.         
  683.         return( (dev->dhandle>=0 ? dev->buf[dev->curr_pos++] : (WORD) Bconin( dev->bios )) & 0xff );
  684.     }
  685.     
  686.     return( -1 );
  687. }
  688.  
  689. /*-------------------------------------------------------------------*/ 
  690.  
  691. GLOBAL WORD PortPeekByte( DEV_LIST *port )
  692. {
  693.     DEVICES    *dev;
  694.     
  695.     dev = (DEVICES *) port;
  696.     
  697.     if( dev->dhandle>=0 )
  698.     {
  699.         if( CharAvailable( port ) )
  700.             return( dev->buf[dev->curr_pos] & 0xff );
  701.     }
  702.     else if( dev->bios>=0 );
  703.     {
  704.         IOREC    *iorec;
  705.         
  706.         iorec = dev->func_map->iorec;
  707.         
  708.         if( iorec->ibufhd!=iorec->ibuftl )
  709.         {
  710.             WORD    pos=iorec->ibufhd;
  711.     
  712.             if( pos>=iorec->ibufsiz )
  713.                 pos = 0;
  714.         
  715.             return( iorec->ibuf[pos] & 0xff );
  716.         }
  717.     }
  718.     
  719.     return( -1 );
  720. }
  721.  
  722. /*-------------------------------------------------------------------*/ 
  723.  
  724. GLOBAL BOOLEAN OutIsEmpty( DEV_LIST *port )
  725. {
  726.     DEVICES    *dev;
  727.     IOREC    *iorec;
  728.     
  729.     dev = (DEVICES *) port;
  730.     
  731.     if( dev->dhandle>=0 )
  732.     {
  733.         if( !Fcntl( dev->dhandle, cntrls, TIONOTSEND ) )
  734.             return( cntrls[0]==0L );
  735.     }
  736.     
  737.     iorec = dev->func_map->iorec;
  738.     iorec++;
  739.     
  740.     return( iorec->ibufhd==iorec->ibuftl );
  741. }
  742.  
  743. /*-------------------------------------------------------------------*/ 
  744.  
  745. GLOBAL BOOLEAN WaitOutEmpty( DEV_LIST *port, BOOLEAN tst_dcd, UWORD wait )
  746. {
  747.     ULONG    time_to_wait;
  748.     
  749.     if( wait )
  750.         time_to_wait = Calc200Hz( (ULONG) wait );
  751.         
  752.     while( !OutIsEmpty( port ) )
  753.     {
  754.         if( (tst_dcd && !IsCarrier( port ))        ||
  755.             (wait    && time_to_wait<Get200Hz( )) )
  756.         {
  757.             ClearIOBuffer( port, IO_O_BUFFER );
  758.             return( FALSE );
  759.         }
  760.         
  761.         if( pause_1 )
  762.             pause_1( );
  763.     }
  764.     
  765.     return( TRUE );
  766. }
  767.  
  768. /*-------------------------------------------------------------------*/ 
  769.  
  770. GLOBAL BOOLEAN CharAvailable( DEV_LIST *port )
  771. {
  772.     DEVICES    *dev;
  773.     
  774.     dev = (DEVICES *) port;
  775.     
  776.     if( dev->dhandle>=0 )
  777.         return( dev->num_read>dev->curr_pos || DevicePickup( dev ) );
  778.     else if( dev->bios>=0 )
  779.         return( Bconstat( dev->bios )<0L );
  780.     
  781.     return( FALSE );
  782. }
  783.  
  784. /*-------------------------------------------------------------------*/ 
  785.  
  786. GLOBAL VOID ClearIOBuffer( DEV_LIST *port, LONG io )
  787. {
  788.     DEVICES    *dev;
  789.     IOREC    *iorec;
  790.     
  791.     dev = (DEVICES *) port;
  792.     
  793.     if( dev->dhandle>=0 )
  794.     {
  795.         if( !Fcntl( dev->dhandle, io, TIOCFLUSH ) )
  796.         {
  797.             if( io!=IO_O_BUFFER )
  798.             {
  799.                 dev->curr_pos = 0;
  800.                 dev->num_read = -1;
  801.                 StartReceiver( port );
  802.             }
  803.             return;
  804.         }
  805.     }
  806.     
  807.     iorec = dev->func_map->iorec;
  808.     
  809.     if( io!=IO_O_BUFFER )
  810.     {
  811.         /* Inbuffer löschen: */
  812.         iorec->ibuftl = iorec->ibufhd;
  813.         dev->curr_pos = 0;
  814.         dev->num_read = -1;
  815.         StartReceiver( port );
  816.     }
  817.  
  818.     if( io!=IO_I_BUFFER )
  819.     {
  820.         /* Outbuffer löschen: */
  821.         iorec++;
  822.         iorec->ibufhd = iorec->ibuftl;
  823.     }
  824. }
  825.  
  826. /*-------------------------------------------------------------------*/ 
  827.  
  828. GLOBAL VOID DtrOn( DEV_LIST *port )
  829. {
  830.     DEVICES    *dev;
  831.     
  832.     dev = (DEVICES *) port;
  833.     
  834.     if( dev->dhandle>=0 && dev->ioctrlmap[0] & TIOCM_DTR )
  835.     {
  836.         cntrls[0] = cntrls[1] = TIOCM_DTR;
  837.         
  838.         Fcntl( dev->dhandle, cntrls, TIOCCTLSET );
  839.     }
  840.     else if( dev->func_num )
  841.         high_dtr( dev->func_num-1, dev->func_map );
  842. }
  843.  
  844. /*-------------------------------------------------------------------*/ 
  845.  
  846. GLOBAL VOID DtrOff( DEV_LIST *port )
  847. {
  848.     DEVICES    *dev;
  849.     
  850.     dev = (DEVICES *) port;
  851.     
  852.     if( dev->dhandle>=0 && dev->ioctrlmap[0] & TIOCM_DTR )
  853.     {
  854.         cntrls[0] = TIOCM_DTR;
  855.         cntrls[1] = 0;
  856.         
  857.         Fcntl( dev->dhandle, cntrls, TIOCCTLSET );
  858.     }
  859.     else if( dev->func_num )
  860.         low_dtr( dev->func_num-1, dev->func_map );
  861. }
  862.  
  863. /*-------------------------------------------------------------------*/ 
  864.  
  865. GLOBAL BOOLEAN IsCarrier( DEV_LIST *port )
  866. {
  867.     DEVICES    *dev;
  868.     
  869.     dev = (DEVICES *) port;
  870.     
  871.     if( dev->dhandle>=0 &&
  872.         dev->ioctrlmap[0] & TIOCM_CAR )
  873.     {
  874.         cntrls[0] = TIOCM_CAR;
  875.         
  876.         Fcntl( dev->dhandle, cntrls, TIOCCTLGET );
  877.         
  878.         return( (UWORD) cntrls[0] & TIOCM_CAR );
  879.     }
  880.     else
  881.     if( dev->func_num )
  882.         return( is_dcd( dev->func_num-1 ) );
  883.     
  884.     return( TRUE );
  885. }
  886.  
  887. /*-------------------------------------------------------------------*/ 
  888.  
  889. GLOBAL VOID PortParameter( DEV_LIST *port, UWORD flowctl, UWORD charlen, UWORD stopbits, UWORD parity )
  890. {
  891.     DEVICES    *dev;
  892.     
  893.     dev = (DEVICES *) port;
  894.     
  895.     if( dev->dhandle>=0 )
  896.     {
  897.         UWORD    flags;
  898.         
  899.         if( !Fcntl( dev->dhandle, &flags, TIOCGFLAGS ) )
  900.         {
  901.             flags &= ~(TF_STOPBITS|TF_CHARBITS|TF_FLAG);
  902.             flags |= (flowctl|charlen|stopbits|parity);
  903.         
  904.             Fcntl( dev->dhandle, &flags, TIOCSFLAGS );
  905.             return;
  906.         }
  907.     }
  908.     
  909.     if( dev->bios==1 || dev->bios>5 )
  910.     {
  911.         LONG    flags;
  912.         UCR        ucr;
  913.         
  914.         if( has_bconmap && dev->bios>5 )
  915.             Bconmap( dev->bios );
  916.     
  917.         flags = Rsconf( -1, -1, -1, -1, -1, -1 );
  918.         
  919.         ucr.word = *((BYTE *) &flags);
  920.         ucr.word &= 0x0081;
  921.         
  922.         if( parity )
  923.         {
  924.             ucr.bits.bit2 = 1;
  925.             if( parity==_EVENP )
  926.                 ucr.bits.bit1 = 1;
  927.         }
  928.         
  929.         ucr.bits.bit3_4 = stopbits;
  930.         ucr.bits.bit5_6 = charlen>>2;
  931.         
  932.         Rsconf( -1, flowctl, ucr.word, -1, -1, -1 );
  933.     }
  934. }
  935.  
  936. /*-----------------------------*/
  937. /*--- local functions       ---*/
  938. /*-----------------------------*/
  939.  
  940. /*-------------------------------------------------------------------*/ 
  941.  
  942. LOCAL BOOLEAN InitStdDevices( MAPTAB *maps, BOOLEAN has_bconmap, WORD num_devices )
  943. {
  944.     DEVICES    *dptr, *dwalk=NULL;
  945.     WORD    loop, i;
  946.  
  947.     if( !has_bconmap || !num_devices )
  948.         num_devices = 1;
  949.     
  950.     loop = (num_devices>4) ? 4 : num_devices;
  951.     
  952.     for( i=1; i<=loop; i++ )
  953.     {
  954.         if( (dptr=(DEVICES *) calloc( 1, sizeof( DEVICES ) ))==NULL )
  955.             return( FALSE );
  956.         
  957.         if( dwalk )
  958.             dwalk->device.next = (DEV_LIST *) dptr;
  959.         else
  960.             devices = dptr;
  961.         
  962.         dwalk = dptr;
  963.  
  964.         switch( i )
  965.         {
  966.             case 1:
  967.                     if( atari!=3 || num_devices!=1 )
  968.                     {
  969.                         dwalk->bios        = (has_bconmap) ? 6 : 1;
  970.                         dwalk->func_num    = 6 - BMAPSTART;
  971.                         dwalk->device.name = d_name[0];
  972.                         if( has_drv_u )
  973.                             dwalk->dopen   = d_open[0];
  974.                         break;
  975.                     }
  976.             case 2:
  977.                     dwalk->bios        = 7;
  978.                     dwalk->func_num    = 7 - BMAPSTART;
  979.                     dwalk->device.name = d_name[1];
  980.                     if( has_drv_u )
  981.                         dwalk->dopen   = d_open[1];
  982.                     break;
  983.             case 3:
  984.                     dwalk->bios = 8;
  985.                     if( atari==1 )
  986.                     {
  987.                         dwalk->func_num    = 9 - BMAPSTART;
  988.                         dwalk->device.name = d_name[3];
  989.                         if( has_drv_u )
  990.                             dwalk->dopen   = d_open[3];
  991.                     }
  992.                     else
  993.                     {
  994.                         dwalk->func_num    = 8 - BMAPSTART;
  995.                         dwalk->device.name = d_name[2];
  996.                         if( has_drv_u )
  997.                             dwalk->dopen   = d_open[2];
  998.                     }
  999.                     break;
  1000.             case 4:
  1001.                     dwalk->bios        = 9;
  1002.                     dwalk->func_num    = 9 - BMAPSTART;
  1003.                     dwalk->device.name = d_name[3];
  1004.                     if( has_drv_u )
  1005.                         dwalk->dopen   = d_open[3];
  1006.                     break;
  1007.         }
  1008.  
  1009.         dwalk->dhandle = -1;
  1010.         dwalk->num_read = -1;
  1011.         
  1012.         if( has_bconmap )
  1013.             dwalk->func_map = &maps[dwalk->bios-6];
  1014.         else if( i==1 )
  1015.             SetMapM1( &dwalk->func_map );
  1016.     }
  1017.     
  1018.     if( (dptr=(DEVICES *) calloc( 1, sizeof( DEVICES ) ))==NULL )
  1019.         return( FALSE );
  1020.         
  1021.     dwalk->device.next = (DEV_LIST *) dptr;
  1022.     
  1023.     dptr->bios        = 3;
  1024.     dptr->device.name = d_name[4];
  1025.     dptr->dhandle     = -1;
  1026.     dptr->num_read    = -1;
  1027.     SetMapMidi( &dptr->func_map );
  1028.     
  1029.     return( TRUE );
  1030. }
  1031.  
  1032. /*-------------------------------------------------------------------*/ 
  1033.  
  1034. LOCAL BOOLEAN InitRSVFDevices( MAPTAB *maps, RSVF_DEV *dev )
  1035. {
  1036.     DEVICES        *dwalk;
  1037.     
  1038.     while( dev->ptr )
  1039.     {
  1040.         if( !(dev->typ.device) )
  1041.         {
  1042.             dev = dev->ptr;
  1043.             continue;
  1044.         }
  1045.         
  1046.         dwalk = devices;
  1047.         
  1048.         while( dwalk )
  1049.         {
  1050.             if( (dwalk->bios==dev->bios_nr && strcmp( dev->ptr, "LAN" )) ||
  1051.                 (!strcmp( dev->ptr, "MIDI" ) && dwalk->bios==3) )
  1052.             {
  1053.                 if( dwalk->bios==3 )
  1054.                     dwalk->bios = (dev->typ.bios) ? dev->bios_nr : 3;
  1055.                 break;
  1056.             }
  1057.             
  1058.             dwalk = (DEVICES *) dwalk->device.next;
  1059.         }
  1060.         
  1061.         if( !dwalk )
  1062.         {
  1063.             DEVICES *dptr;
  1064.             
  1065.             if( (dptr=(DEVICES *) calloc( 1, sizeof( DEVICES ) ))==NULL )
  1066.                 return( FALSE );
  1067.             
  1068.             dwalk = devices;
  1069.             while( dwalk->device.next )
  1070.                 dwalk = (DEVICES *) dwalk->device.next;
  1071.             
  1072.             dwalk->device.next = (DEV_LIST *) dptr;
  1073.             dwalk              = dptr;
  1074.  
  1075.             dwalk->device.name = (BYTE *) dev->ptr;
  1076.             dwalk->bios        = (dev->typ.bios) ? dev->bios_nr : -1;
  1077.             
  1078.             dwalk->dhandle = -1;
  1079.             dwalk->num_read = -1;
  1080.             
  1081.             dwalk->func_map = (dwalk->bios>5) ? &maps[dwalk->bios-6] : NULL;
  1082.         }
  1083.         
  1084.         dwalk->dopen = (BYTE *) dev->ptr;
  1085.         
  1086.         dev++;
  1087.     }
  1088.     
  1089.     return( TRUE );
  1090. }
  1091.  
  1092. /*-------------------------------------------------------------------*/ 
  1093.  
  1094. LOCAL BOOLEAN CreateSpeedlist( DEVICES *dev )
  1095. {
  1096.     if( (dev->speeds=(LONG *) calloc( MAX_SPEEDS, sizeof( LONG * ) ))==NULL )
  1097.         return( FALSE );
  1098.     
  1099.     if( dev->dhandle>=0 )
  1100.         GetFcntlSpeeds( dev );
  1101.     else if( dev->bios==3 )        /* Midi */
  1102.     {
  1103.         LONG    *a_ptr, *b_ptr;
  1104.         
  1105.         a_ptr = midi_speeds;
  1106.         b_ptr = dev->speeds;
  1107.         
  1108.         while( *a_ptr>0 )
  1109.             *b_ptr++ = *a_ptr++;
  1110.         
  1111.         *b_ptr = *a_ptr;
  1112.         
  1113.         dev->device.curr_dte = 31250;
  1114.     }
  1115.     else if( fser )
  1116.         GetFserSpeeds( dev );
  1117.     else
  1118.     {
  1119.         WORD    i;
  1120.         LONG    *a_ptr, *b_ptr;
  1121.         
  1122.         if( tos<=0x104 )
  1123.             i = *((WORD *)((BYTE *) dev->func_map->iorec + 34));
  1124.         else
  1125.             i = (WORD) Rsconf( -2, -1, -1, -1, -1, -1 );
  1126.  
  1127.         a_ptr = speeds;
  1128.         
  1129.         while( i )
  1130.         {
  1131.             i--;
  1132.             a_ptr++;
  1133.         }
  1134.         dev->device.curr_dte = *a_ptr;
  1135.         
  1136.         a_ptr = speeds;
  1137.         b_ptr = dev->speeds;
  1138.  
  1139.         while( *a_ptr>0 )
  1140.             *b_ptr++ = *a_ptr++;
  1141.         
  1142.         *b_ptr = *a_ptr;
  1143.     }
  1144.     
  1145.     return( TRUE );    
  1146. }
  1147.  
  1148. /*-------------------------------------------------------------------*/ 
  1149.  
  1150. LOCAL VOID GetFcntlSpeeds( DEVICES *dev )
  1151. {
  1152.     LONG    *dte_ptr;
  1153.     LONG    last_dte, dte;
  1154.     
  1155.     /*
  1156.      * Aktuelle DTE-Speed retten:
  1157.      */
  1158.     dev->device.curr_dte = -1;
  1159.     Fcntl( dev->dhandle, &dev->device.curr_dte, TIOCIBAUD );
  1160.     
  1161.     /*
  1162.      * Von hohen zu niedrigen Baudraten wandern, solange es
  1163.      * noch weitere gibt:
  1164.      */
  1165.     dte_ptr  = dev->speeds;
  1166.     last_dte = dte = 0x7fffffffL;
  1167.     
  1168.     while( TRUE )
  1169.     {
  1170.         Fcntl( dev->dhandle, &dte, TIOCIBAUD );
  1171.  
  1172.         if( dte>=last_dte )
  1173.         {
  1174.             *dte_ptr = -1;
  1175.             break;
  1176.         }
  1177.         else
  1178.             last_dte = *dte_ptr++ = dte;
  1179.         
  1180.         dte--;
  1181.     }
  1182.     
  1183.     /*
  1184.      * DTE-Speed wiederherstellen:
  1185.      */    
  1186.     Fcntl( dev->dhandle, &dev->device.curr_dte, TIOCIBAUD );
  1187.     
  1188.     return;
  1189. }
  1190.  
  1191. /*-------------------------------------------------------------------*/ 
  1192.  
  1193. LOCAL VOID GetFserSpeeds( DEVICES *dev )
  1194. {
  1195.     BAUD_INFO    *walk, *table;
  1196.     WORD        i, nums;
  1197.     LONG        *lptr;
  1198.         
  1199.     table = (fser->baud_table_flag) ? dev->chan_info->alt_baud_table : dev->chan_info->baud_table;
  1200.     nums  = 0;
  1201.  
  1202.     i    = (WORD) Rsconf( -2, -1, -1, -1, -1, -1 );
  1203.     walk = table;    
  1204.     
  1205.     while( i )
  1206.     {
  1207.         walk++;
  1208.         i--;
  1209.     }
  1210.     dev->device.curr_dte = walk->baudrate;
  1211.     
  1212.     walk = table;
  1213.     
  1214.     while( walk->baudrate )
  1215.     {
  1216.         if( walk->baudrate>0 )
  1217.         {
  1218.             lptr = dev->speeds;
  1219.         
  1220.             for( i=0; i<nums; i++ )
  1221.             {
  1222.                 if( walk->baudrate>=*lptr )
  1223.                     break;
  1224.                 lptr++;
  1225.             }
  1226.             
  1227.             if( i<nums && !(walk->baudrate==*lptr) )
  1228.                 memcpy( lptr+1, lptr, (nums-i) * sizeof( LONG ) );
  1229.             else if( i!=nums )
  1230.             {
  1231.                 walk++;
  1232.                 continue;
  1233.             }
  1234.                 
  1235.             *lptr = walk->baudrate;
  1236.             nums++;
  1237.         }
  1238.         walk++;
  1239.     }
  1240.     
  1241.     dev->speeds[nums] = -1;
  1242.     
  1243.     return;
  1244. }
  1245.  
  1246. /*-------------------------------------------------------------------*/ 
  1247.  
  1248. LOCAL VOID FreeSpeedlist( DEVICES *dev )
  1249. {
  1250.     if( dev->speeds )
  1251.     {
  1252.         free( dev->speeds );
  1253.         dev->speeds = NULL;
  1254.     }
  1255. }
  1256.  
  1257. /*-------------------------------------------------------------------*/ 
  1258.  
  1259. LOCAL VOID SetDevFunctions( DEVICES *dev )
  1260. {
  1261.     if( dev->dhandle>=0 )
  1262.         Fcntl( dev->dhandle, dev->ioctrlmap, TIOCCTLMAP );
  1263. }
  1264.  
  1265. /*-------------------------------------------------------------------*/ 
  1266.  
  1267. LOCAL VOID SetPortProtokoll( DEVICES *dev )
  1268. {
  1269.     UWORD    flow=_RTSCTS;
  1270.     
  1271.     if( dev->dhandle>=0 && !strcmp( dev->dopen, "MIDI" ) )
  1272.         flow = _XONXOFF;
  1273.     
  1274.     PortParameter( (DEV_LIST *) dev, flow, _8BIT, _1STOP, _NO_PARITY );
  1275.     
  1276.     /*
  1277.      * Unter MiNT muß noch der Terminal-Typ "raw" eingestellt
  1278.      * werden (grrrrr!):
  1279.      */
  1280.     if( dev->dhandle>=0 && !rsvf && MiNT )
  1281.     {
  1282.         SGTTYB tty;
  1283.         
  1284.         if( !Fcntl( dev->dhandle, &tty, TIOCGETP ) )
  1285.         {
  1286.             tty.sg_flags = T_RAW;
  1287.             Fcntl( dev->dhandle, &tty, TIOCSETP );
  1288.             Fcntl( dev->dhandle, &tty, TIOCGETP );
  1289.         }
  1290.     }
  1291. }
  1292.  
  1293. /*-------------------------------------------------------------------*/ 
  1294.  
  1295. LOCAL BOOLEAN DevicePickup( DEVICES *dev )
  1296. {
  1297.     LONG    count;
  1298.  
  1299.     dev->curr_pos = 0;
  1300.     dev->num_read = -1;
  1301.     
  1302.     if( (count=Fread( dev->dhandle, MAX_BLOCK, dev->buf ))<=0 )
  1303.         return( FALSE );
  1304.         
  1305.     dev->num_read = (WORD) count;
  1306.     
  1307.     return( TRUE );
  1308. }
  1309.  
  1310. /*-------------------------------------------------------------------*/ 
  1311.  
  1312. LOCAL BOOLEAN DeviceSendBlock( DEVICES *dev, BYTE *block, LONG len, BOOLEAN tst_dcd )
  1313. {
  1314.     LONG    sent=0L, help;
  1315.     LONG    timeout=0;
  1316.     
  1317.     while( sent<len )
  1318.     {
  1319.         if( tst_dcd && !IsCarrier( (DEV_LIST *) dev ) )
  1320.             return( FALSE );
  1321.  
  1322.         if( (help=Fwrite( dev->dhandle, len-sent, block+sent ))<0L )
  1323.             return( FALSE );
  1324.         
  1325.         sent += help;
  1326.         
  1327.         if( sent<len )
  1328.         {
  1329.             if( !timeout )
  1330.                 timeout = Calc200Hz( 500L );
  1331.             else
  1332.             if( timeout<Get200Hz( ) )
  1333.                 break;
  1334.             
  1335.             if( pause_1 )
  1336.                 pause_1( );
  1337.         }
  1338.     }
  1339.     
  1340.     return( TRUE );
  1341. }
  1342.